/*================================================================
*   Copyright (C) 2024 baichao All rights reserved.
*
*   文件名称：pipe2.c
*   创 建 者：baichao
*   创建日期：2024年04月06日
*   描
述：当最后一个读取端关闭时，向管道写入会触发SIGPIPE信号，同时write会返回失败，errno为EPIPE。
*
================================================================*/

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void sighandler(int signo);
int main(void) {
  int fds[2];
  if (signal(SIGPIPE, sighandler) == SIG_ERR) {
    fprintf(stderr, "signal error (%s)\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
  if (pipe(fds) == -1) {
    fprintf(stderr, "create pipe failed(%s)\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
  pid_t pid;
  pid = fork();
  if (pid == -1) {
    fprintf(stderr, "fork error (%s)\n", strerror(errno));
    exit(EXIT_FAILURE);
  }
  if (pid == 0) {
    fprintf(stdout, "[CHILD ] I will close the last read end of pipe \n");
    close(fds[0]);  // 子进程关闭读取端文件描述符
    exit(EXIT_SUCCESS);
  }
  close(fds[0]);  // 父进程关闭读取端文件描述符
  sleep(1);       // 确保子进程也将读取端关闭
  int ret;
  ret = write(fds[1], "hello", 5);
  if (ret == -1) {
    fprintf(stderr, "[PARENT] write error(%s)\n", strerror(errno));
  }
  return 0;
}
void sighandler(int signo) {
  printf("[PARENT] catch a SIGPIPE signal and signum = %d\n", signo);
}
